/**
 * 心跳检测
 * @param socketInstance socket实例
 * @constructor
 */
function HeartCheck(socketInstance) {
  this.socketInstance = socketInstance;
  this.timerSeconds = 60;
  this.timer = null;
}

/**
 * 启动心跳检查
 */
HeartCheck.prototype.start = function () {
  let socketInstance = this.socketInstance;
  this.timer = setTimeout(() => {
    if (socketInstance != null) {
      socketInstance.send(JSON.stringify({
        eventType: 'heart',
        data: 'heartCheck'
      }));
    }
  }, this.timerSeconds * 1000)
}

/**
 * 重置心跳检查
 */
HeartCheck.prototype.reset = function () {
  clearTimeout(this.timer);
  this.start(this.socketInstance);
}


/**
 * socket封装实例
 * 若在组件中使用初始化，请在组件销毁时调用 destroy() 否则可能存在多个socket同时连接的情况
 * @param userName 连接用户
 * @param settings 连接配置
 * @constructor
 */
function SySocket(userName, settings) {
  //默认配置
  let defaultSettings = {
    //是否自动重连
    autoReconnect: true,
    userName: '',
    url: '',
    //是否打开心跳连接检查
    heartCheckOpen: false,
    //当前重连次数
    currentReconnectCount: 0,
    //最大重连次数
    maxReconnectCount: 10,
    //10秒重连一次
    perReconnectCost: 3
  };
  this.instance = null;
  this.timer = null;
  this.userName = userName;
  this.settings = {
    ...defaultSettings,
    ...(settings || {}),
    userName: userName
  };
  this.heartCheck = new HeartCheck(this.instance);
  //连接
  this.connect();
}

/**
 * 执行连接
 */
SySocket.prototype.connect = function () {
  let useSSL = location.href.indexOf('https')===0;
  let url = this.settings.url || `${useSSL?'wss':'ws'}://${process.env.VUE_APP_SERVER}/ws/msg/${this.settings.userName}`;
  this.instance = new WebSocket(url);

  //消息打开时事件
  this.instance.onopen = e => {
    console.log(this.settings.userName + '-->>连接成功打开');
    //打开连接时刷新数据

    //心跳检测
    if (this.settings.heartCheckOpen) {
      this.heartCheck.start();
    }

    //自定义回调函数:
    if (this.settings.onopen) {
      this.settings.onopen(e);
    }
  }

  //接收消息事件
  this.instance.onmessage = (e) => {
    //接收消息时 提示信息并刷新数据
    let eventData = JSON.parse(e.data);
    console.log(this.settings.userName + '-->>接收消息数据:', eventData);
    //根据事件类型做相关操作
    if (window.globalEventHandler) {
      //触发事件
      window.globalEventHandler.$emit(eventData.eventType, eventData);
    }

    //重置心跳检测
    if (this.settings.heartCheckOpen) {
      this.heartCheck.reset();
    }

    //自定义回调函数:
    if (this.settings.onmessage) {
      this.settings.onmessage(e);
    }
  }

  //关闭事件 断线重连
  this.instance.onclose = e => {
    console.log(this.settings.userName + '-->>连接关闭');
    //关闭时自动重连
    if (this.settings.autoReconnect) {
      this.reconnect();
    }

    //自定义回调函数:
    if (this.settings.onclose) {
      this.settings.onclose(e);
    }
  }

  //错误事件
  this.instance.onerror = e => {
    console.log(this.settings.userName + '-->>连接异常，报错信息如下：', e);
    //报错时自动重连
    // this.reconnect();


    //自定义回调函数:
    if (this.settings.onerror) {
      this.settings.onerror(e);
    }
  }
}

/**
 * 重连
 */
SySocket.prototype.reconnect = function () {
  if (!this.settings.autoReconnect) {
    return;
  }
  console.log(this.settings.userName + '-->> 正在自动重连');
  //销毁
  let maxReconnectCount = this.settings.maxReconnectCount;
  let currentReconnectCount = this.settings.currentReconnectCount;
  if (currentReconnectCount < maxReconnectCount) {
    if (this.timer) {
      clearTimeout(this.timer);
    }
    this.settings.currentReconnectCount = currentReconnectCount + 1;
    this.timer = setTimeout(() => {
      this.connect();
    }, this.settings.perReconnectCost * 1000)
  }
}

/**
 * 销毁
 */
SySocket.prototype.destroy = function () {
  if (this.instance) {
    this.settings.autoReconnect = false;
    this.instance.close();
    this.instance = null;
  }
}

/**
 * socket封装实例
 * 若在组件中使用初始化，请在组件销毁时调用 socket.destroy() 否则可能存在多个socket同时连接的情况
 */
export default SySocket
